﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JigLibX.Math;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using PloobsEngine.Modelo.Animation;
using PloobsEngine.Physics.XJigLib;
using PloobsEngine.Publishers;
using PloobsEngine.Commands;
using PloobsEngine.Tasks;

namespace PloobsEngine.Behaviors
{
    public class CharacterMovimentationBehavior : IBehavior
    {
        private float amount = 10;        
        private CharacterMovimentationAction cma;
        private IAction ac1;

        private static ActionPublishInformation apiB = new ActionPublishInformation(NAME, MOVEBACK,null);
        private static ActionPublishInformation apiF = new ActionPublishInformation(NAME, MOVEFRONT,null);
        private static ActionPublishInformation apiL = new ActionPublishInformation(NAME, MOVELEFT,null);
        private static ActionPublishInformation apiR = new ActionPublishInformation(NAME, MOVERIGHT,null);
        private static ActionPublishInformation apiS = new ActionPublishInformation(NAME, STOPPED,null);
        private static ActionPublishInformation apiStopping = new ActionPublishInformation(NAME, STOPPING,null);
        private ActionPublishInformation collideFalse = new ActionPublishInformation(IsCollidingAction.NOT_COLLIDING, null, null);

        public CharacterMovimentationBehavior(CharacterObject character)
        {
            cma = new CharacterMovimentationAction(character);
            ac1 = new IsCollidingAction(character as JigLibXObject);
            
            task = new StopMovimentTask(this);
        }

        public CharacterMovimentationBehavior(CharacterObject character, float speed, float rot)
            : this(character,speed)
        {
            cma.setRotation(rot);
        }

        public CharacterMovimentationBehavior(CharacterObject character, float speed)
        {
            cma = new CharacterMovimentationAction(character);
            this.amount = speed * 10;
            task = new StopMovimentTask(this);
        }

        public void setSpeed(float amount)
        {
            this.amount = amount * 10;
        }


        #region IBehavior Members

        Vector3 move; //= Vector3.Zero;
        StopMovimentTask task;
        float multiplier = 1;
        CharacterMovimentationAction.DIRECTION dir;

        public void setMultiplier(float mult)
        {
            lock (this)
            {
                this.multiplier = mult;
            }
        }


        public void PerformBehavior(String state, object data)
        {

            if (ac1.Action() == IsCollidingAction.COLLIDING)
            {
                dir = CharacterMovimentationAction.DIRECTION.Stopping;
                switch (state)
                {
                    case MOVERIGHT:

                        dir = CharacterMovimentationAction.DIRECTION.Right;
                        //move += Vector3.Right;
                        //move = Vector3.Forward;
                        Notify(apiR);
                        task.restart();
                        break;
                    case MOVELEFT:

                        dir = CharacterMovimentationAction.DIRECTION.Left;
                        //move += Vector3.Left;
                        //move = Vector3.Forward;
                        Notify(apiL);
                        task.restart();
                        break;
                    case MOVEFRONT:
                        dir = CharacterMovimentationAction.DIRECTION.Front;
                        //move += Vector3.Forward;
                        Notify(apiF);
                        task.restart();
                        break;
                    case MOVEBACK:
                        dir = CharacterMovimentationAction.DIRECTION.Back;
                        //move += Vector3.Backward;
                        //move = Vector3.Forward;
                        Notify(apiB);
                        task.restart();
                        break;
                    case null:
                        dir = CharacterMovimentationAction.DIRECTION.Stopping;
                        apiStopping.Information = multiplier * amount;
                        Notify(apiStopping);
                        break;
                }

                cma.setSpeed(multiplier * amount);
                cma.setDirection(dir);
                cma.Action();
               
            }
            
                     else
            {
                Notify(collideFalse);
            }
           


            if (task.Activate == false)
            {
                task.Activate = true;
                TaskCommand tc = new TaskCommand(task);
                CommandProcessor.getCommandProcessor().SendCommandAssyncronous(tc);
            }
            if (multiplier <= 0)
            {
                task.Activate = false;
                Notify(apiS);
                multiplier = 1;
            }

        }

        #endregion

        private ISubject _sub = new ConcreteSubject();
        #region ISubject Members
        public int ObserverNumber()
        {
            return _sub.ObserverNumber();
        }

        public void Attach(IObserver obs)
        {
            _sub.Attach(obs);
        }

        public void Dettach(IObserver obs)
        {
            _sub.Dettach(obs);
        }

        public void DettachAll()
        {
            _sub.DettachAll();
        }

        public void Notify(object obj)
        {
            _sub.Notify(obj);
        }

        #endregion

        #region IBehavior Members


        public string BehaviorName
        {
            get { return NAME; }
        }
        public const String NAME = "CHARACTERMOVIMENTATIONBEHAVIOR";
        public const String MOVERIGHT = "MOVERIGHT";
        public const String MOVELEFT = "MOVELEFT";
        public const String MOVEFRONT = "MOVEFRONT";
        public const String MOVEBACK = "MOVEBACK";
        public const String MOVEJUMP = "MOVEJUMP";
        public const String STOPPED = "STOPPED";
        public const String STOPPING = "STOPPING";
        #endregion

        #region IBehavior Members


        private IList<IAction> actionsList = new List<IAction>();
        public IList<IAction> Actions
        {
            get { return actionsList; }
        }

        #endregion

        #region IBehavior Members


        public void Release()
        {
            
        }

        #endregion
    }
}